package org.example;

import javassist.*;

import java.io.IOException;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.security.ProtectionDomain;
import java.util.ArrayList;
import java.util.List;

public class ClazzTransformer implements ClassFileTransformer {
    public static final List<String> INJECTED_CLASS = new ArrayList<String>();

    static {
        //被代理的类
        INJECTED_CLASS.add("org.example.AgentInstrumentationTest");
    }

    @Override
    public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
                            ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
        /** 直接打印 className
         * className---java/util/Properties$LineReader
         * className---java/net/Inet6Address
         * className---sun/misc/URLClassPath$FileLoader$1
         * className---java/net/URI
         * className---org/example/AgentInstrumentationTest
         */
        String realClassName = className.replace("/", ".");
        try {
            if (INJECTED_CLASS.contains(realClassName)) {
                System.out.println("ClazzTransformer类transform方法,Agent class:" + realClassName+"----Runtime.getRuntime="+
                        Runtime.getRuntime());
                ClassPool classPool = ClassPool.getDefault();
                CtClass ctClass = classPool.get(realClassName);
                CtMethod[] declaredMethods = ctClass.getDeclaredMethods();

                for (CtMethod ctMethod : declaredMethods) {
                    if (ctMethod.getName().equals("process")) {
                        String method = ctMethod.getName();
                        ctMethod.insertBefore(String.format("System.out.println(\"Process method:%s---Runtime.getRuntime=\" +Runtime.getRuntime());", method));
                        ctMethod.insertBefore(" System.out.println(\"方法开始了111----start\"); ");
                        ctMethod.insertAfter(" System.out.println(\"方法结束了222----end\"); ");
                        ctMethod.insertAfter(" System.out.println(); ");
                    }
                }
                return ctClass.toBytecode();
            }
        } catch (NotFoundException | CannotCompileException | IOException e) {
            e.printStackTrace();
        }
        return classfileBuffer;
    }
}
